﻿using System;
using System.Linq;
using System.Windows.Input;

namespace Wheels.Windows
{
	public class EventCommand
		: EventCommand<object>
	{ }

#pragma warning disable 1591

    public class EventCommand<T>
		: ICommand
	{
		public bool CanExecute(object parameter)
		{
			if ((parameter != null) && !(parameter is T)) return false;
			if (CanExecuteCalled == null) return true;

			var args = new CommandCanExecuteEventArgs<T>((T)parameter);

			//CanExecuteCalled(this, args);
			//return args.CanExecute;

			var handlers = CanExecuteCalled.GetInvocationList().Cast<EventHandler<CommandCanExecuteEventArgs<T>>>();
			return handlers.All(handler =>
			{
				handler.Invoke(this, args);
				return args.CanExecute;
			});
		}

		public event EventHandler<CommandEventArgs<T>> Called;
		public event EventHandler<CommandCanExecuteEventArgs<T>> CanExecuteCalled;
		public event EventHandler CanExecuteChanged;

		public void Execute(object parameter)
		{
			if ((parameter != null) && !(parameter is T))
				throw new ArgumentOutOfRangeException();

			Execute((T)parameter);
		}

		public void Execute(T parameter)
		{
			if (Called != null)
				Called(this, new CommandEventArgs<T>(parameter));
		}

		public void FireCanExecuteChanged()
		{
			if (CanExecuteChanged == null) return;

			CanExecuteChanged(this, new EventArgs());
		}
	}
}
